package com.starblink.brand.detail.ui

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.apollographql.apollo3.api.Optional
import com.starblink.android.basic.base.BaseViewModel
import com.starblink.android.basic.network.base.SkGqlClient
import com.starblink.android.basic.widget.LoadingDialogManager
import com.starblink.basic.apollo.ext.optional
import com.starblink.basic.log.SKLogger
import com.starblink.basic.util.ActivityStackManage
import com.starblink.brand.BrandHelper
import com.starblink.brand.detail.bean.RvBrandCategoryEntry
import com.starblink.brand.detail.bean.RvTopBrandEntry
import com.starblink.brand.search.bean.RvProductWapper
import com.starblink.library.widget.sort.SortTypeEnum
import com.starblink.rocketreserver.FetchBrandCollectionListV2Query
import com.starblink.rocketreserver.FetchTopBrandFrontCategoryListQuery
import com.starblink.rocketreserver.FetchTopBrandInfoQuery
import com.starblink.rocketreserver.FetchTopBrandProductListQuery
import com.starblink.rocketreserver.fragment.TopBrandInfoVOF
import com.starblink.rocketreserver.type.TopBrandFrontCategoryReq
import com.starblink.rocketreserver.type.TopBrandInfoReq
import com.starblink.rocketreserver.type.TopBrandProductListReq
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.launch

class BrandDetailVM : BaseViewModel() {
    // ===页面传参
    var brandId: Int = 0
    var exposureBrandIds: ArrayList<Int>? = null
    // ===页面传参

    var brandName = ""
    var showCategory: Boolean = true // 显示三级目录

    // 排序方式： 0-默认排序 2-价格从高到低 3-价格从低到高 4-折扣从高到低 5-折扣从低到高
    var sortType: SortTypeEnum = SortTypeEnum.DEFAULT
    var categoryId: Int = 0 //选择的品牌目录ID，默认0表示ALL
    var isDiscountBrand = false //是否是折扣品牌，默认false

    var pageRefreshDataLD: MutableLiveData<PageRefreshData> = MutableLiveData() //页面刷新数据

    class PageRefreshData {
        var excludeTopBrands: Boolean = false // 是否排除头部折扣品牌，true-页面内切换品牌时使用；false-打开页面时使用
        var brandInfo: TopBrandInfoVOF? = null // null表示接口请求失败，显示错误视图
        var discountBrand = false
        var topBrands: List<RvTopBrandEntry>? =
            null // 如果是非折扣品牌为null，不显示Top品牌列表；如果是折扣品牌，null表示接口请求失败，显示错误视图
        var brandCategories: List<RvBrandCategoryEntry>? = null // 如果目录为null，不显示目录视图
        var brandProducts: List<RvProductWapper>? = null // null表示接口请求失败，显示错误视图
    }

    companion object {
        const val ERROR_LOAD_FIRST_PAGE_DATA_FAIL = 1 // 加载首页数据失败
        const val ERROR_LOAD_CHANGE_BRAND_DATA_FAIL = 5 // 切换品牌加载数据失败
        const val ERROR_LOAD_BRAND_PRODUCTS_FAIL = 2 //获取品牌店铺失败
        const val ERROR_LOAD_MORE_BRAND_CATEGORIES_FAIL = 3 //获取品牌目录失败
        const val ERROR_LOAD_MORE_TOP_BRANDS_FAIL = 4 //获取头部折扣品牌失败
    }

    /**
     * 页面切换品牌
     */
    fun changeBrand() {
        // 重置基础数据
        this.sortType = SortTypeEnum.DEFAULT
        this.categoryId = 0

        loadPageData(excludeTopBrands = true, showGlobalLoading = false)
    }

    var loadPageDataJob: Job? = null

    /**
     * 加载页面数据（4个接口)
     * @param excludeTopBrands 是否排除头部折扣品牌，true-页面内切换品牌时使用；false-打开页面时使用
     * @param showGlobalLoading 是否显示全局Loading
     */
    fun loadPageData(excludeTopBrands: Boolean = false, showGlobalLoading: Boolean = true) {
        SKLogger.e("dss2", "77777, loadPageData, brandId = $brandId")

        if (loadPageDataJob?.isActive == true) {
            SKLogger.e("dss2", "loadPageDataJob?.isActive == true, cancel job")
            loadPageDataJob?.cancel()
        }

        //1.首先加载品牌信息
        //1.1如果加载失败显示错误页面
        //1.2如果加载成功，并发加载剩余3种数据
        //1.2.1Top品牌列表（分页）
        //1.2.2三级目录（分页）
        //1.2.3品牌商品数据（分页）
        loadPageDataJob = viewModelScope.launch {
            val curBrandId = brandId
            if (showGlobalLoading) {
                LoadingDialogManager.get()
                    .showLoading(ActivityStackManage.currentActivity())
            }
            var brandInfo: TopBrandInfoVOF? = null
            // 加载品牌信息
            SkGqlClient.skQuery(
                FetchTopBrandInfoQuery(
                    TopBrandInfoReq(
                        brandId = curBrandId.optional(),
                    )
                )
            )?.data?.fetchTopBrandInfo?.topBrandInfoVOF?.let {
                // 获取数据成功
                brandInfo = it
                isDiscountBrand = it.brandDiscount != null
                brandName = it.name ?: ""
                SKLogger.e("dss2", "66666, 获取数据成功, brandId = $curBrandId")
            } ?: let {
                // 获取数据失败
                SKLogger.e("dss2", "44444, loadError, brandId = $curBrandId")
                if(curBrandId == brandId){ // 过滤被取消Job的失败数据
                    loadError(
                        if (excludeTopBrands) ERROR_LOAD_CHANGE_BRAND_DATA_FAIL
                        else ERROR_LOAD_FIRST_PAGE_DATA_FAIL
                    )
                }
                return@launch
            }

            // 并发加载Top品牌列表+品牌目录+品牌商品
            var topBrandsDeffer: Deferred<List<RvTopBrandEntry>?>? = null
            if (isDiscountBrand && !excludeTopBrands) {
                // 仅当折扣品牌，并且首页刷新时，请求Top品牌列表
                topBrandsDeffer = async {
                    SKLogger.e("dss", "5555")
                    loadTopBrands(true)
                }
            }

            val brandCategoriesDeffer = async {
                SKLogger.e("dss", "6666")
                loadBrandCategories(true)
            }

            val brandProductsDeffer = async {
                SKLogger.e("dss", "7777")
                loadBrandProducts(true)
            }

            // 处理目录数据
            var brandCategories = brandCategoriesDeffer.await()
            if (brandCategories.isNullOrEmpty() || brandCategories.size < 2) {
                showCategory = false
                brandCategories = null
            } else {
                showCategory = true
            }

            val brandProducts = brandProductsDeffer.await()
            // 必须手动重置bigCard字段值！！！
            // 如果显示目录，显示小卡，否则大卡
            if (showCategory && brandProducts.isNullOrEmpty().not()) {
                brandProducts?.forEach {
                    it.bigCard = !showCategory
                }
            }

            // 返回结果
            val data = PageRefreshData().apply {
                this.excludeTopBrands = excludeTopBrands
                this.brandInfo = brandInfo
                this.discountBrand = isDiscountBrand
                this.topBrands = topBrandsDeffer?.await()
                this.brandCategories = brandCategories
                this.brandProducts = brandProducts
            }
            SKLogger.e("dss2", "55555, pageRefreshDataLD.postValue(data), brandId = $curBrandId")
            pageRefreshDataLD.postValue(data)
        }
    }

    var curPageNoTopBrands = 0 // Top品牌列表当前页数，默认是0
    var loadMoreTopBrandsLD: MutableLiveData<List<RvTopBrandEntry>> =
        MutableLiveData() //加载更多Top品牌

    /**
     * 加载Top品牌列表
     */
    private suspend fun loadTopBrands(refresh: Boolean): List<RvTopBrandEntry>? {
        val requestPageNo = if (refresh) 1 else curPageNoTopBrands + 1
        var brands = SkGqlClient.skQuery(
            FetchBrandCollectionListV2Query(
                pageNo = requestPageNo,
                pageSize = 20,
                isPullDownRefresh = false,
                scene = 1,
                clickBrandId = brandId.optional(),
                exposureBrandIdList = if (exposureBrandIds == null) Optional.Absent else exposureBrandIds.optional()
            )
        )?.data?.fetchBrandCollectionListV2?.brandList
            ?.filter { it?.brandVOF?.brandId != null }
            ?.mapNotNull { RvTopBrandEntry(brandVO = it!!.brandVOF) }
            ?: return null // 请求失败，返回null

        // 列表第一项，默认选中
        if (refresh && brands.isNotEmpty()) {
            brands[0].isSelected = brands[0].brandVO?.brandId == brandId
        }

        // 请求成功，页数+1
        curPageNoTopBrands = requestPageNo

        return brands
    }

    /**
     * 加载更多Top品牌列表
     */
    fun loadMoreTopBrands() {
        viewModelScope.launch {
            val data = loadTopBrands(false)
            SKLogger.e("dss3", "loadMoreTopBrands, data={${data}}")
            if (data == null) {
                loadError(ERROR_LOAD_MORE_TOP_BRANDS_FAIL)
            } else {
                loadMoreTopBrandsLD.postValue(data!!)
            }
        }
    }

    var curPageNoBrandCategories = 0 // 品牌三级目录列表当前页数，默认是0
    var loadMoreBrandCategoriesLD: MutableLiveData<List<RvBrandCategoryEntry>> =
        MutableLiveData() //加载更多品牌三级目录

    /**
     * 加载品牌三级目录
     * @note 加载失败，不显示目录视图
     */
    private suspend fun loadBrandCategories(refresh: Boolean): List<RvBrandCategoryEntry>? {
        val requestPageNo = if (refresh) 1 else curPageNoBrandCategories + 1
        var items = SkGqlClient.skQuery(
            FetchTopBrandFrontCategoryListQuery(
                TopBrandFrontCategoryReq(
                    pageNo = requestPageNo,
                    pageSize = 20,
                    brandId = brandId,
                    isSale = false
                )
            )
        )?.data?.fetchTopBrandFrontCategoryList
            ?.filter { it?.categoryF?.id != null && !it.categoryF.name.isNullOrEmpty() }
            ?.map {
                RvBrandCategoryEntry(
                    name = it!!.categoryF.name!!,
                    id = (it.categoryF.id!! as Int)
                )
            }
            ?: return null // 请求失败，返回null

        val result = mutableListOf<RvBrandCategoryEntry>()
        items.forEach { result.add(it) }

        // 如果首页目录，目录数量>=2，手动添加ALL
        if (refresh && result.size >= 2) {
            result.add(0, RvBrandCategoryEntry(name = "All", id = 0))
        }

        // 请求成功，页数+1
        curPageNoBrandCategories = requestPageNo

        return result
    }

    /**
     * 加载更多品牌三级目录
     */
    fun loadMoreBrandCategories() {
        viewModelScope.launch {
            val data = loadBrandCategories(false)
            if (data == null) {
                loadError(ERROR_LOAD_MORE_BRAND_CATEGORIES_FAIL)
            } else {
                loadMoreBrandCategoriesLD.postValue(data!!)
            }
        }
    }

    var curPageNoBrandProducts = 0
    var loadMoreBrandProductsLD: MutableLiveData<List<RvProductWapper>> =
        MutableLiveData()
    var refreshBrandProductsLD: MutableLiveData<List<RvProductWapper>> =
        MutableLiveData()

    /**
     * 加载品牌商品列表
     */
    private suspend fun loadBrandProducts(refresh: Boolean): List<RvProductWapper>? {
        val requestPageNo = if (refresh) 1 else curPageNoBrandProducts + 1
        var items = SkGqlClient.skQuery(
            FetchTopBrandProductListQuery(
                TopBrandProductListReq(
                    pageNo = requestPageNo,
                    pageSize = 20,
                    brandId = brandId,
                    brandName = brandName,
                    isSale = false,
                    sortType = sortType.code,
                    foregroundCategoryId = if (categoryId == 0) Optional.Absent else categoryId.optional(), // ALL时不传
                )
            )
        )?.data?.fetchTopBrandProductList?.filter { it?.productF != null }
            ?.map {
                RvProductWapper(
                    product = it!!.productF,
                    showSimpleView = BrandHelper.showSimpleViewInBrandDetail,
                    bigCard = !showCategory
                )
            }
            ?: return null // 请求失败，返回null

        // 请求成功，页数+1
        curPageNoBrandProducts = requestPageNo

        return items
    }

    fun refreshBrandProducts(showDialogLoading: Boolean = false) {
        viewModelScope.launch {
            if (showDialogLoading) {
                LoadingDialogManager.get()
                    .showLoading(ActivityStackManage.currentActivity())
            }
            val data = loadBrandProducts(true)
            if (data == null) {
                loadError(ERROR_LOAD_BRAND_PRODUCTS_FAIL)
            } else {
                refreshBrandProductsLD.postValue(data!!)
            }
            if (showDialogLoading) {
                LoadingDialogManager.get().dismissLoading()
            }
        }
    }

    /**加载更多品牌商品列表*/
    fun loadMoreBrandProducts() {
        viewModelScope.launch {
            val data = loadBrandProducts(false)
            if (data == null) {
                loadError(ERROR_LOAD_BRAND_PRODUCTS_FAIL)
            } else {
                loadMoreBrandProductsLD.postValue(data!!)
            }
        }
    }
}